#Binary parser template

import os, sys
from Sanae3D.lib.ModelObject import Model3D

#Tokens

T_NAME = 1
T_STRING = 2
T_INTEGER = 3
T_GUID = 5
T_INTEGER_LIST = 6
T_REALNUM_LIST = 7
T_OBRACE = 10
T_CBRACE = 11
T_OPAREN = 12
T_CPAREN = 13
T_OBRACKET = 14
T_CBRACKET = 15
T_OANGLE = 16
T_CANGLE = 17
T_DOT = 18
T_COMMA = 19
T_SEMICOLON = 20
T_TEMPLATE = 31
T_WORD = 40
T_DWORD = 41
T_FLOAT = 42
T_DOUBLE = 43
T_CHAR = 44
T_UCHAR = 45
T_SWORD = 46
T_SDWORD = 47
T_VOID = 48
T_LPSTR = 49
T_UNICODE = 50
T_CSTRING = 51
T_ARRAY = 52

class BinX_Parser(Model3D):
    '''.x binary format parser'''
    
    templates = set(("Frame", "FrameTransformMatrix", "Mesh", "MeshNormals", 
                 "MeshTextureCoords", "XSkinMeshHeader", "SkinWeights",
                 "MeshMaterialList", "Material", "TextureFilename", "template",
                 "AnimTicksPerSecond", "MeshFace", "MeshVertexColors",
                 "Animation", "AnimationSet", "TimedFloatKeys",
                 "AnimationKey", "VertexDuplicationIndices", "Header")
                 )
    
    def __init__(self, obj3D=None, inFile=None, outFile=None):
        
        super(BinX_Parser, self).__init__("X")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
        self.frameStack = []
        self.tempStack = []
        self.tempCount = 0
        self.xMats = []
        self.matReference = False
        
    def start_temp(self, tempType):
        
        self.tempStack.append(template)
        
    def get_temp(self):
        
        return self.tempStack[-1]
        
    def end_temp(self):
        
        self.tempStack.pop()
        
    def get_name(self):
        
        token_name = self.inFile.read_short()
        count = self.inFile.read_long()
        return self.inFile.read_string(count)
    
    def get_primitive(self):
        
        primitive = self.inFile.read_short()
        print self.get_name()
        semicolon = self.inFile.read_short()
    
    def get_guid(self):
        
        self.inFile.seek(18, 1) #short, 16-byte
        
    def get_array_data_type(self):
        
        self.inFile.read_short()
        print self.get_name()
        
    def get_dimension_list(self):
        
        pass
        
    def get_array(self):
        
        tokenArray = self.inFile.read_short()
        self.get_array_data_type()
        print self.get_name()
        self.get_dimension_list()
        
    def parse_template_parts(self):
        
        self.parse_template_members_part()
        obracket = self.inFile.read_short()
        self.parse_template_options_info()
        cbracket = self.inFile.read_short()
    
    def parse_template_members_part(self):
        
        self.parse_template_members_list()
    
    def parse_template_options_info(self):
        
        ellipsis = self.inFile.read_short(3)
        self.parse_template_option_list()
        
    def parse_template_option_list(self):
        
        print self.get_name()
        token = self.inFile.tell()
        guid = self.inFile.read(16)
    
    def parse_template_members_list(self):
        
        self.parse_template_members()
    
    def parse_template_members(self):
        
        primitive = self.inFile.read_short()
        print self.inFile.tell()
        print self.get_name()
        self.parse_template_reference()
        
    def parse_template_reference(self):
        
        pass
        
    def parse_template(self):
        
        template_name = self.get_name()
        print template_name
        obrace = self.inFile.read_short()
        self.get_guid()
        self.parse_template_parts()
        cbrace = self.inFile.read_short()
        
    def parse_file(self):
        '''Main parser method. Can be replaced'''
        
        self.inFile.read(16)
        print "bin parser", self.inFile.tell()
        
        token = self.inFile.read_short()
        while token:
            if token == T_TEMPLATE:
                #self.start_temp("Template")
                self.parse_template()
            elif token == T_OBRACE:
                template = self.get_temp()
                self.end_temp()
            token = self.inFile.read_short()
        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = BinX_Parser(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

if __name__ == '__main__':
    
    file1 = "amulet_001.X"
    obj = read_file(file1)